/**
 * 
 */
package org.vsg.stock.dzh;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.vsg.common.configration.PropertiesSupport;
import org.vsg.common.exceptions.service.ServiceException;
import org.vsg.stock.basic.StockHelper;
import org.vsg.stock.basic.domain.StockCategory;
import org.vsg.stock.basic.domain.StockDailyLine;
import org.vsg.stock.basic.persistence.StockCategoryDao;
import org.vsg.stock.basic.persistence.StockInfoDao;
import org.vsg.stock.extension.service.StockAnalysisService;
import org.vsg.stock.extension.vo.LinkageStock;
import org.vsg.stock.extension.vo.LinkageStockGroup;


/**
 * @author vison
 *
 */
public class StkCategoryLinkageIndexBuilder {

	private final static Logger logger = LoggerFactory.getLogger(StkCategoryLinkageIndexBuilder.class);	
	
	static private DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
	

	private String encoding;

	
	public void exec(ApplicationContext appContext , Date fromDate , Date toDate) throws Exception {

		PropertiesSupport proSupport = (PropertiesSupport)appContext.getBean("propertyConfigurer");		
		
		encoding = proSupport.getProperties().getProperty("file.encoding");

		String dir = proSupport.getProperties().getProperty("stock.linkage.dir");
		if (dir == null) {
			//logger.warn("Property 'stock.dailyline.dirk' is not defined! ");
			throw new Exception("Property 'stock.linkage.dir' is not defined!");
		}		
		
		StockAnalysisService stkAnalyService = (StockAnalysisService)appContext.getBean("stockAnalysisService");
		StockCategoryDao stockCategoryDao = (StockCategoryDao)appContext.getBean("stockCategoryDao");
		
		// get the date period 
		List<LinkageStockGroup> linkageStockGroupList = null;
		Map<String, StockCategory> cateMap = new HashMap<String,StockCategory>();
		try {
			linkageStockGroupList = stkAnalyService.findStockGroupListInPeriod(fromDate, toDate, 3);

			LinkageStockGroup linkageStkGroup = null;
			StringBuffer builder = new StringBuffer();
			StockCategory stockCategory = null;
			List<LinkageStock> linkageStkList = null;
			LinkageStock linkageStock = null;
			StringBuffer assoStocks = null;
			File file = null;
			Date tradingDate = null;
			StockHelper helper = StockHelper.getInstance();
			for (Iterator<LinkageStockGroup> linkageStkGroupIter = linkageStockGroupList.iterator() ; linkageStkGroupIter.hasNext(); ) {
				linkageStkGroup = linkageStkGroupIter.next();
				
				tradingDate = linkageStkGroup.getDate();
				// --- build the file ---
				file = new File(dir, sdf.format( tradingDate )+".txt");

				if (!helper.isTradingDate( tradingDate ) || file.exists()) {
					continue;
				}
				
				OutputStream os = null;
				try {
					
					linkageStkList = linkageStkGroup.getLinkageStockList();

					for (Iterator<LinkageStock> linkageStkIter = linkageStkList.iterator() ; linkageStkIter.hasNext(); ) {
						linkageStock = linkageStkIter.next();
						stockCategory = linkageStock.getStockCategory();
						
						builder.append(stockCategory.getId()).append(",");
						builder.append(stockCategory.getDescription()).append(",");
						builder.append(linkageStock.getCount()).append(",");					
						builder.append(linkageStock.getAvgRatio()).append(",");					

						String type = stockCategory.getType();
						
						if (StockCategory.SAME_STOCKHOLDER.equalsIgnoreCase(type)) {
							builder.append(StockCategory.SAME_STOCKHOLDER);
						}
						else if (StockCategory.CONCEPT.equalsIgnoreCase(type)) {
							builder.append(StockCategory.CONCEPT);
						}
						else if (StockCategory.OTHERS.equalsIgnoreCase(type)) {
							builder.append(StockCategory.OTHERS);					
						}				
						else if (StockCategory.PLATE.equalsIgnoreCase(type)) {
							builder.append(StockCategory.PLATE);					
						}				
						else if (StockCategory.STANDARD_TRADES.equalsIgnoreCase(type)) {
							builder.append(StockCategory.STANDARD_TRADES);					
						}				
						else if (StockCategory.TRADES.equalsIgnoreCase(type)) {
							builder.append(StockCategory.TRADES);					
						}				
						else if (StockCategory.ZONE.equalsIgnoreCase(type)) {
							builder.append(StockCategory.ZONE);					
						}
						
						assoStocks = new StringBuffer();
						
						List<StockDailyLine> assoList = linkageStock.getAssoStocks();
						for (Iterator<StockDailyLine> assoListIter = assoList.iterator() ; assoListIter.hasNext();) {
							assoStocks.append( assoListIter.next().getStockCode() );
							
							if (assoListIter.hasNext()) {
								assoStocks.append("|");
							}
						}
						builder.append(",").append( assoStocks );
						
						if (linkageStkIter.hasNext()) {
							builder.append("\n");
						}
						
					}
					
					os = new BufferedOutputStream(new FileOutputStream(file));
					
					IOUtils.write( builder, os , "UTF-8");

					// --- clear all data ---
					builder.delete(0, builder.length());
				
				} catch (FileNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				} finally {
					if (os != null) {
						try {
							os.close();
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				}
				

				

			}
		
		} catch (ServiceException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Calendar cale = Calendar.getInstance();

		// --- get the from date and to date ---
		Date fromDate = cale.getTime();
		
		Date toDate = cale.getTime();		
		
		for (String arg : args) {
			if (arg.startsWith("-DfromDate=")) {
				String dateString = arg.replaceFirst("-DfromDate=", "").trim();
				try {
					fromDate = sdf.parse( dateString );
				} catch (ParseException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
			}
			
			if (arg.startsWith("-DtoDate=")) {
				String dateString = arg.replaceFirst("-DtoDate=", "").trim();
				try {
					toDate = sdf.parse( dateString );
				} catch (ParseException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}				
			}
		}
				
		
		ClassLoader clsLoader = StkCategoryLinkageIndexBuilder.class.getClassLoader();
		// --- run the main page ---
		// build the read the path , dzh's home path
		String[] configContextFiles = {
				"classpath:/spring/configurationContext.xml",
				"classpath*:/spring/applicationContext.xml",
				"classpath*:/spring/dataAccessContext.xml"
		};
		
		ApplicationContext ctx = new ClassPathXmlApplicationContext(configContextFiles,true);
		
	
		StkCategoryLinkageIndexBuilder mainProg = new StkCategoryLinkageIndexBuilder();
		
		try {
			mainProg.exec(ctx , fromDate , toDate);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
		logger.info("program run ... Ok!");
		



	}

}
